using System;
using System.ComponentModel;
using System.Linq.Expressions;
#if NETFX_CORE
using Windows.UI.Core;
#else
using System.Windows.Threading;
#endif

namespace FreshMeat.Xaml
{
   public class PropertyNotifier
   {
      readonly Func<PropertyChangedEventHandler> getHandler;
      readonly object sender;
#if NETFX_CORE
      readonly CoreDispatcher dispatcher;
#else
      readonly Dispatcher dispatcher;
#endif

#if NETFX_CORE
      public PropertyNotifier(object sender, CoreDispatcher dispatcher, Func<PropertyChangedEventHandler> getHandler)
#else
      public PropertyNotifier(object sender, Dispatcher dispatcher, Func<PropertyChangedEventHandler> getHandler)
#endif
      {
         this.sender = sender;
         this.dispatcher = dispatcher;
         this.getHandler = getHandler;
      }

      public void ChangedAll()
      {
         Changed("");
      }

      public void Changed<T>(params Expression<Func<T>>[] propertyExpressions)
      {
         Changed(PropertyAccessor.GetNames(propertyExpressions));
      }

      public void Changed(params string[] names)
      {
#if NETFX_CORE
         if (dispatcher.HasThreadAccess)
#else
         if (dispatcher.CheckAccess())
#endif
         {
            var handler = getHandler();
            if (handler != null)
            {
               foreach (var name in names)
                  handler(sender, new PropertyChangedEventArgs(name));
            }
         }
         else
         {
            Post(() => Changed(names));
         }
      }

#if NETFX_CORE
      async void Post(Action action)
#else
      void Post(Action action)
#endif
      {
#if NETFX_CORE
         await dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(action));
#else
         dispatcher.BeginInvoke(action);
#endif
      }
   }
}